package com.rule.lang.parser;

import com.rule.dsl.resolver.DSLKeywordResolver;
import com.rule.dsl.resolver.DSLResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * DSL 解析器服务
 * 要解析 DSL 相关关键字，我们需要实现一个关键字解析器
 *
 */
@Slf4j
@Service
public class DSLParser {

    @Autowired
    private DSLKeywordResolver keywordResolver;

    @Autowired
    private DSLPatternUtil dslPatternUtil;
    /**
     * 它采用给定的规则表达式并解析 DSL 关键字，并将规则表达式中的值替换为相应的关键字
     */
    public String resolveDomainSpecificKeywords(String expression){
        Map<String, Object> dslKeywordToResolverValueMap = executeDSLResolver(expression);
        //替换关键字
        /**
         * 输入 condition: “input.monthlySalary >= 50000 && input.creditScore >= 800 && input.requestedLoanAmount<4000000 && $(bank.target_done) == false”条件：“input.monthlySalary >= 50000 && input.creditScore >= 800 && input.requestedLoanAmount<4000000 && $(bank.target_done) == false”
         * 输出 condition: “input.monthlySalary >= 50000 && input.creditScore >= 800 && input.requestedLoanAmount<4000000 && false == false”条件：“input.monthlySalary >= 50000 && input.creditScore >= 800 && input.requestedLoanAmount<4000000 && false == false”
         */
        return replaceKeywordsWithValue(expression, dslKeywordToResolverValueMap);
    }

    private Map<String, Object> executeDSLResolver(String expression) {
        List<String> listOfDslKeyword = dslPatternUtil.getListOfDslKeywords(expression);
        Map<String, Object> dslKeywordToResolverValueMap = new HashMap<>();
        listOfDslKeyword.stream()
                .forEach(
                        dslKeyword -> {
                            String extractedDslKeyword = dslPatternUtil.extractKeyword(dslKeyword);
                            String keyResolver = dslPatternUtil.getKeywordResolver(extractedDslKeyword);
                            String keywordValue = dslPatternUtil.getKeywordValue(extractedDslKeyword);
                            DSLResolver resolver = keywordResolver.getResolver(keyResolver).get();
                            Object resolveValue = resolver.resolveValue(keywordValue);
                            dslKeywordToResolverValueMap.put(dslKeyword, resolveValue);
                        }
                );
        return dslKeywordToResolverValueMap;
    }

    private String replaceKeywordsWithValue(String expression, Map<String, Object> dslKeywordToResolverValueMap){
        List<String> keyList = dslKeywordToResolverValueMap.keySet().stream().collect(Collectors.toList());
        for (int index = 0; index < keyList.size(); index++){
            String key = keyList.get(index);
            String dslResolveValue = dslKeywordToResolverValueMap.get(key).toString();
            expression = expression.replace(key, dslResolveValue);
        }
        return expression;
    }
}
